home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
utilitys
/
less_14z
/
part03
< prev
next >
Wrap
Internet Message Format
|
1991-07-08
|
60KB
Path: news.larc.nasa.gov!amiga-request
From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
Subject: v91i129: Less 1.4Z - text pager, Part03/07
Reply-To: rayz@altair.csustan.edu (R. L. Zarling)
Newsgroups: comp.sources.amiga
Message-ID: <comp.sources.amiga.v91i129@ab20.larc.nasa.gov>
References: <comp.sources.amiga.v91i127@ab20.larc.nasa.gov>
Date: 04 Jul 91 17:28:18 GMT
Approved: tadguy@uunet.UU.NET (Tad Guy)
X-Mail-Submissions-To: amiga@uunet.uu.net
X-Post-Discussions-To: comp.sys.amiga.misc
Submitted-by: rayz@altair.csustan.edu (R. L. Zarling)
Posting-number: Volume 91, Issue 129
Archive-name: utilities/less-1.4z/part03
#!/bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 7)."
# Contents: Less1.4Z/src/io.c Less1.4Z/src/main.c
# Less1.4Z/src/screen.c
# Wrapped by tadguy@ab20 on Thu Jul 4 13:28:15 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Less1.4Z/src/io.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Less1.4Z/src/io.c'\"
else
echo shar: Extracting \"'Less1.4Z/src/io.c'\" \(17649 characters\)
sed "s/^X//" >'Less1.4Z/src/io.c' <<'END_OF_FILE'
X/* io.c */
X
X#ifdef AMIGA
X/* Compile with -HPreHeader.q to get "less.h"! */
X#else
X#include "less.h"
X#endif
X
X#include <ctype.h>
X#include <string.h>
X#include <intuition/intuition.h>
X#include <dos.h>
X
X
X#undef TRUE
X#undef FALSE
X
Xextern int sigs;
X
Xstatic struct ConCom *tty = NULL;
X
Xpublic int nrow = 0; /* Terminal size, rows. */
Xpublic int ncol; /* Terminal size, columns. */
X
Xstatic struct Window *LessWindow;
X
Xint Wind_Spec[4] = { 0, 0, 0, 0 };
X/* User-supplied option specifying window size/position:
X *
X * [0]: Left edge X - coord.
X * [1]: Top edge Y - coord.
X * [2]: Right edge X - coord.
X * [3]: Bottom edge Y - coord.
X *
X * If element 2 or 3 is negative, it is taken to be a relative value to be
X * subtracted from the maximum screen size. If the resulting window
X * would be smaller than the minimum, it is quietly enlarged to the
X * minimum, by expanding to the lower right as far as possible, and then
X * moving the window toward the upper left if necessary.
X */
X#define W_MINWIDTH 200
X#define W_MINHEIGHT 60
X
Xextern char version[];
X
X/* Prototypes for functions defined in io.c */
X
Xstatic struct ConCom *OpenConsole __PROTO((struct Window *window));
Xstatic void CloseConsole __PROTO((struct ConCom *tty));
Xstatic void StartTtyTimer __PROTO((void));
Xstatic void StartConRead __PROTO((struct ConCom *tty));
Xstatic int ConGetC __PROTO((struct ConCom *tty));
Xstatic int ConLookC __PROTO((struct ConCom *tty));
Xstatic void ConWrite __PROTO((struct ConCom *tty,
X char *data,
X int length));
X
X
X
X/****************************************************************/
X/* Code to open a console on an existing Intuition window.
X See RKM Libraries & Devices, pp 277 ff
X*/
X
X#include <exec/memory.h>
X#include <devices/timer.h>
X
Xextern struct GfxBase *GfxBase;
Xextern struct IOStdReq * CreateStdIO();
Xextern struct MsgPort *CreatePort();
X
X
Xstruct ConCom
X{
X struct IOStdReq *ConWriteReq; /* I/O write request */
X struct IOStdReq *ConReadReq; /* I/O read request */
X struct MsgPort *RdReplyPort; /* pointer to ReplyPort for console read */
X struct timerequest *TimerMsg; /* If != NULL, timer is open */
X};
X
X
Xstatic struct ConCom *OpenConsole ( struct Window *window );
Xstatic void CloseConsole ( struct ConCom *tty );
Xstatic void StartConRead ( struct ConCom *tty );
Xstatic int ConGetC ( struct ConCom *tty );
Xstatic int ConLookC ( struct ConCom *tty );
Xstatic void ConWrite ( struct ConCom *c, char *data, int length );
X
Xstatic struct ConCom *OpenConsole (struct Window *window)
X{
X struct ConCom *tty;
X struct MsgPort *WrReplyPort, *TimerPort;
X
X if ( tty = (struct ConCom *)
X AllocMem(sizeof(struct ConCom), MEMF_CLEAR | MEMF_PUBLIC) )
X {
X
X if ( (WrReplyPort = CreatePort(0, 0)) /* reply port for write */
X
X && (tty->RdReplyPort = CreatePort(0, 0)) /* reply port for read */
X
X && (tty->ConWriteReq = CreateStdIO ( WrReplyPort ))
X
X && (tty->ConReadReq = CreateStdIO ( tty->RdReplyPort)) )
X {
X tty->ConWriteReq->io_Data = (APTR) window;
X tty->ConWriteReq->io_Length = sizeof(struct Window);
X
X if ( !(OpenDevice ( "console.device", 0, tty->ConWriteReq, 0 )) )
X {
X tty->ConReadReq->io_Device = tty->ConWriteReq->io_Device;
X tty->ConReadReq->io_Unit = tty->ConWriteReq->io_Unit;
X
X /* Try to set up regular interrupts for ^C check */
X TimerPort = CreatePort(NULL, 0);
X if (
X TimerPort
X && ( tty->TimerMsg = (struct timerequest *)
X CreateExtIO(TimerPort, sizeof(struct timerequest)) )
X && !OpenDevice (TIMERNAME, UNIT_VBLANK,
X (struct IORequest *)(tty->TimerMsg), 0)
X )
X return tty; /* All ok! */
X /* Main console ports ok, but no timer. We'll live
X without it...
X */
X if ( TimerPort ) DeletePort ( TimerPort );
X if ( tty->TimerMsg )
X DeleteExtIO( (struct IORequest *)(tty->TimerMsg),
X (long)sizeof(struct timerequest) );
X tty->TimerMsg = NULL;
X return tty;
X }
X }
X
X /* If get here, something went wrong */
X if ( tty->ConReadReq ) DeleteStdIO(tty->ConReadReq);
X if ( tty->RdReplyPort ) DeletePort(tty->RdReplyPort);
X if ( tty->ConWriteReq ) DeleteStdIO(tty->ConWriteReq);
X if ( WrReplyPort ) DeletePort(WrReplyPort);
X }
X if ( tty )
X FreeMem(tty, sizeof(struct ConCom));
X return NULL;
X
X}
X
Xstatic void CloseConsole (struct ConCom *tty)
X{
X struct MsgPort *mp;
X
X AbortIO(tty->ConReadReq); /* Abort any read in progress */
X CloseDevice(tty->ConWriteReq); /* close console device */
X
X mp = tty->ConWriteReq->io_Message.mn_ReplyPort;
X
X DeleteStdIO(tty->ConWriteReq);
X DeletePort(mp);
X
X mp = tty->ConReadReq->io_Message.mn_ReplyPort;
X
X DeleteStdIO(tty->ConReadReq);
X DeletePort(mp);
X
X if (tty->TimerMsg)
X {
X AbortIO((struct IORequest *)(tty->TimerMsg));
X CloseDevice((struct IORequest *)(tty->TimerMsg));
X DeletePort ( tty->TimerMsg->tr_node.io_Message.mn_ReplyPort );
X DeleteExtIO ( (struct IORequest *)(tty->TimerMsg),
X (long)sizeof(struct timerequest) );
X }
X
X FreeMem(tty, sizeof(struct ConCom));
X return;
X}
X
X/* Request a timer interrupt in 0.25 seconds. Use this to poll for ^C */
X
Xstatic void StartTtyTimer (void)
X{
X if ( !tty->TimerMsg ) return;
X tty->TimerMsg->tr_node.io_Command = TR_ADDREQUEST;
X tty->TimerMsg->tr_time.tv_secs = 0;
X tty->TimerMsg->tr_time.tv_micro = 250000L;
X SendIO ( (struct IORequest *)(tty->TimerMsg) );
X}
X
Xstatic char buffer; /* buffer for incoming console character */
X
X/* asynchronous console read request--must be called once before
X any ConGetC requests
X*/
X
Xstatic void StartConRead (struct ConCom *tty)
X{
X struct IOStdReq *conr;
X
X conr = tty->ConReadReq;
X conr->io_Command = CMD_READ;
X conr->io_Length = 1;
X conr->io_Data = (APTR) &buffer;
X SendIO(conr); /* asynchronous posting of a read request */
X}
X
X/* Get a character from the console.
X*/
Xstatic int ConGetC (struct ConCom *tty)
X{
X struct MsgPort *mp, *tp;
X struct IOStdReq *rddata;
X int temp;
X ULONG ReadMsgBit, ClockMsgBit, MsgBits;
X
X mp = tty->RdReplyPort; /* get the read reply port */
X ReadMsgBit = 1 << mp->mp_SigBit;
X if ( tty->TimerMsg )
X {
X tp = tty->TimerMsg->tr_node.io_Message.mn_ReplyPort;
X ClockMsgBit = 1 << tp->mp_SigBit;
X }
X else ClockMsgBit = 0;
X rddata = NULL;
X do /* Wait for a character. Wake up periodically so that ^C works */
X {
X MsgBits = Wait(ReadMsgBit | ClockMsgBit);
X if ( MsgBits & ReadMsgBit )
X rddata = (struct IOStdReq *) GetMsg ( mp );
X if ( MsgBits & ClockMsgBit )
X if ( GetMsg (tp) )
X {
X StartTtyTimer();
X chkabort();
X }
X } while ( !rddata );
X
X /* We've got a character... */
X temp = buffer; /* get the character */
X StartConRead ( tty ); /* set up next read */
X return temp;
X}
X
X/* See if a character is available at the console.
X If so, get it, else return -1.
X*/
Xstatic int ConLookC (struct ConCom *tty)
X{
X struct MsgPort *mp;
X struct IOStdReq *rddata;
X int temp;
X
X mp = tty->RdReplyPort; /* get the read reply port */
X rddata = (struct IOStdReq *) GetMsg ( mp );
X if ( !rddata ) return -1;
X
X /* We've got a character... */
X temp = buffer; /* get the character */
X StartConRead ( tty ); /* set up next read */
X return temp;
X}
X
X/* write a specified number of characters from a buffer to console device
X*/
Xstatic void ConWrite (struct ConCom *tty, char *data, int length)
X{
X struct IOStdReq *wrdata;
X
X wrdata = tty->ConWriteReq;
X wrdata->io_Command = CMD_WRITE;
X wrdata->io_Length = length;
X wrdata->io_Data = (APTR) data;
X DoIO(wrdata); /* waits until write completes before continuing */
X}
X
X/****************************************************************/
X
X
X
X/*
X * This routine gets called once, to set up the
X * terminal channel.
X */
Xvoid ttopen (void)
X{
X int wl, wt; /* window upper left corner specification */
X static struct Screen __aligned WBScreen, *wbsdata;
X static int IsV2;
X static struct NewWindow NewLessWindow =
X {
X 0, 0, 640, 200, /* position & size (may be changed) */
X -1, -1, /* pens */
X 0, /* IDCMP */
X WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | WINDOWCLOSE | ACTIVATE
X | SMART_REFRESH | NOCAREREFRESH,
X NULL, NULL, /* Gadgets, Checkmark */
X "Less 1.4Z: h for help",
X NULL, NULL, /* Use WB screen */
X W_MINWIDTH, W_MINHEIGHT, -1, -1,
X WBENCHSCREEN
X };
X
X if (tty) return;
X
X
X if (GfxBase = /* V2.0 + ? */
X (struct GfxBase *)OpenLibrary("graphics.library", 36) )
X {
X CloseLibrary ( GfxBase );
X IsV2 = 1;
X if ( !(wbsdata = LockPubScreen("Workbench")) )
X {
X error ( "Can't find Workbench screen" );
X quit();
X }
X }
X else
X {
X IsV2 = 0;
X if ( !GetScreenData ( &WBScreen, sizeof(struct Screen),
X WBENCHSCREEN, NULL ) )
X {
X error ( "Can't find Workbench screen" );
X quit();
X }
X wbsdata = &WBScreen;
X }
X if ( (wl = Wind_Spec[0]) < 0 ) wl += wbsdata->Width;
X if ( wl < 0 ) wl = 0;
X if ( wl > wbsdata->Width )
X wl = wbsdata->Width - W_MINWIDTH;
X if ( (wt = Wind_Spec[1]) < 0 ) wt += wbsdata->Height;
X if ( wt < 0 ) wt = 0;
X if ( wt > wbsdata->Height )
X wt = wbsdata->Height - W_MINHEIGHT;
X if ( wl < 0 || wt < 0 )
X {
X error ( "Window won't fit on screen" );
X quit();
X }
X NewLessWindow.LeftEdge = wl;
X NewLessWindow.TopEdge = wt;
X
X NewLessWindow.Width = Wind_Spec[2];
X if ( NewLessWindow.Width <= 0 )
X NewLessWindow.Width += wbsdata->Width;
X if ( NewLessWindow.Width <= 0 )
X NewLessWindow.Width = 0;
X NewLessWindow.Height = Wind_Spec[3];
X if ( NewLessWindow.Height <= 0 )
X NewLessWindow.Height += wbsdata->Height;
X if ( NewLessWindow.Height <= 0 )
X NewLessWindow.Height = 0;
X
X if ( NewLessWindow.Width < W_MINWIDTH )
X NewLessWindow.Width = W_MINWIDTH;
X if ( NewLessWindow.Height < W_MINHEIGHT )
X NewLessWindow.Height = W_MINHEIGHT;
X
X if ( NewLessWindow.LeftEdge + NewLessWindow.Width > wbsdata->Width )
X NewLessWindow.Width = wbsdata->Width - NewLessWindow.LeftEdge;
X if ( NewLessWindow.TopEdge + NewLessWindow.Height > wbsdata->Height )
X NewLessWindow.Height = wbsdata->Height - NewLessWindow.TopEdge;
X if ( NewLessWindow.Width < W_MINWIDTH )
X NewLessWindow.LeftEdge = wbsdata->Width - W_MINWIDTH;
X if ( NewLessWindow.Height < W_MINHEIGHT )
X NewLessWindow.TopEdge = wbsdata->Height - W_MINHEIGHT;
X if ( NewLessWindow.LeftEdge < 0 || NewLessWindow.TopEdge < 0 )
X {
X error ( "Window won't fit on screen" );
X quit();
X }
X
X if (IsV2)
X UnlockPubScreen(NULL, wbsdata);
X if (!(LessWindow = (struct Window *) OpenWindow (&NewLessWindow)) )
X {
X error ( "Can't open Less window" );
X quit();
X }
X if (!(tty = OpenConsole(LessWindow)))
X {
X error ( "Can't open console device" );
X quit();
X }
X StartConRead ( tty );
X if ( tty->TimerMsg ) StartTtyTimer();
X /* enable report of window resizeing and close gadget */
X ConWrite(tty, "\x9b\x31\x32;11{", 7);
X}
X
X/* Request size of window information
X*/
Xvoid getrowcol (void)
X{
X static unsigned char buf[16], *p;
X
X if ( !tty) ttopen();
X ConWrite(tty, "\x9b\x30\x20\x71", 4); /* request current window size */
X p = buf;
X while ( (*p = ConGetC(tty)) != 0x9b ) /* nothing */;
X p++;
X do
X {
X *p = ConGetC(tty);
X } while ( p < &(buf[15]) && *p++ != '\x72' );
X *p = '\0';
X /* buf has "En;n;n;n|", where E is 0x9b, n is a decimal number */
X
X p = buf+1;
X do
X {
X if ( p = strchr ( p, ';' ) ) p++; /* skip window position */
X else break;
X if ( p = strchr ( p, ';' ) ) p++;
X else break;
X nrow = atoi ( p ); /* window height */
X if ( p = strchr ( p, ';' ) ) p++;
X else break;
X ncol = atoi ( p ); /* window width */
X } while (0); /* just once! */
X
X /* arbitrary data integrity checks: */
X if ( nrow < 2 || nrow > 99 || ncol < 10 || ncol > 200 )
X {
X /* Window probably too small for the font chosen. We may not
X be able to even write an error message in the window! */
X MyRequester ( "Screen/Font mismatch" );
X quit();
X }
X}
X
X
X
X/*
X * This function gets called just
X * before we go back home to the command interpreter.
X * On the Amiga it closes up the virtual terminal window.
X */
Xvoid ttclose (void)
X{
X if (tty != (struct ConCom *) 0L) {
X CloseConsole(tty);
X CloseWindow(LessWindow);
X }
X tty = NULL;
X nrow = 0;
X}
X
X
X/*
X * Read a character from the terminal,
X * performing no editing and doing conditional echo
X * but interpretting window resize and close gadget reports
X */
Xint do_echo = 1; /* echo flag */
X
Xint ttgetc (void)
X{
X unsigned char c; /* must be unsigned! */
X
X
X while ( (c = ConGetC(tty)) == '\x9b' )
X {
X switch (c = ConGetC(tty))
X {
X case '1': /* raw input event */
X if ( (c = ConGetC(tty)) == '1' )
X quit(); /* close gadget */
X else if ( c == '2' ) /* window resize */
X {
X while ( (c = ConGetC(tty)) != '|') /* nothing */;
X winch();
X }
X break;
X case '?': /* Help key */
X if ( (c = ConGetC(tty)) == '~' ) return 'h';
X break;
X case 'A':
X case 'T': /* Arrow up */
X c = 'b';
X break;
X case 'B':
X case 'S': /* Arrow down */
X c = ' ';
X break;
X case 'D': /* Arrow left */
X c = 'k';
X break;
X case 'C': /* Arrow right */
X c = '\r';
X break;
X case ' ': /* Shifted left or right */
X if ( (c = ConGetC(tty)) == 'A' ) c = 'u';
X else c = 'd';
X break;
X default:
X continue;
X }
X break;
X }
X if ( c == 3 )
X {
X sigs |= 01;
X psignals();
X /* no return */
X }
X if (do_echo)
X ttwrite(&c, 1);
X
X return ((int) c);
X}
X
X/*
X * Check for ^C in the tty window. This routine will throw
X * away any characters waiting in the tty input buffer. Returns when
X * there's nothing in the input queue or one of the following has been
X * recognized:
X *
X * Close gadget (exits)
X * Window resize (resets window and returns)
X * ^C (sets sigs and returns)
X */
Xint chk_sigs (void)
X{
X int c;
X
X for (;;)
X {
X if ( (c = ConLookC(tty)) < 0 ) return sigs;
X
X switch ( c )
X {
X case '\x9b': /* raw input event */
X if ( (c = ConGetC(tty)) != '1' ) break; /* unexpected raw input */
X if ( (c = ConGetC(tty)) == '1' )
X quit(); /* close gadget */
X else if ( c == '2' ) /* window resize */
X {
X while ( (c = ConGetC(tty)) != '|') /* nothing */;
X winch();
X return sigs;
X }
X break;
X case 3:
X sigs |= 01;
X return sigs;
X }
X }
X}
X
X
X
X/*
X * Write a buffer of characters to the display.
X */
Xvoid ttwrite (char *buffer, int length)
X{
X ConWrite ( tty, buffer, length );
X}
X
X/*
X * Write a string to the terminal
X */
Xvoid ttputs (char *s)
X{
X ConWrite ( tty, s, strlen(s) );
X}
X
X/* fake termcap output */
X/* This takes the place of the original tputs(x,y,z), using only the
X first parameter
X */
Xvoid Tputs (char *s)
X{
X flush();
X if ( s ) ConWrite ( tty, s, strlen(s) );
X}
X
X/*
X * We may not have a window: display a message in a requester
X */
Xint MyRequester (char *s)
X{
X static struct IntuiText __aligned
X Ok =
X {
X AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X AUTOLEFTEDGE, AUTOTOPEDGE,
X AUTOITEXTFONT,
X "Ok!",
X AUTONEXTTEXT
X },
X IMsg =
X {
X AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X AUTOLEFTEDGE, AUTOTOPEDGE + 20, /* Hope this is enough for default font */
X AUTOITEXTFONT,
X "",
X AUTONEXTTEXT
X },
X LessMsg =
X {
X AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
X AUTOLEFTEDGE, AUTOTOPEDGE,
X AUTOITEXTFONT,
X "Less 1.4Z:",
X &IMsg
X };
X
X IMsg.IText = s;
X return (int)AutoRequest(NULL, &LessMsg, &Ok, &Ok, NULL, NULL, 250, 80);
X}
END_OF_FILE
if test 17649 -ne `wc -c <'Less1.4Z/src/io.c'`; then
echo shar: \"'Less1.4Z/src/io.c'\" unpacked with wrong size!
fi
# end of 'Less1.4Z/src/io.c'
fi
if test -f 'Less1.4Z/src/main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Less1.4Z/src/main.c'\"
else
echo shar: Extracting \"'Less1.4Z/src/main.c'\" \(16671 characters\)
sed "s/^X//" >'Less1.4Z/src/main.c' <<'END_OF_FILE'
X/*
X * Entry point, initialization, miscellaneous routines.
X */
X
X#ifdef AMIGA
X/* Compile with -HPreHeader.q to get "less.h"! */
X#else
X#include "less.h"
X#endif
X
X#include "position.h"
X#include <setjmp.h>
X#include <signal.h>
X
Xpublic int ispipe;
Xpublic jmp_buf main_loop;
Xpublic char * first_cmd;
Xpublic char * every_first_cmd;
Xpublic int new_file;
Xpublic int is_tty;
Xpublic char current_file[FILENAME];
Xpublic char previous_file[FILENAME];
Xpublic POSITION prev_pos;
Xpublic int any_display;
Xpublic int ac;
Xpublic char ** av;
Xpublic int curr_ac;
X#if LOGFILE
Xpublic int logfile = -1;
Xpublic int force_logfile = 0;
Xpublic char * namelogfile = NULL;
X#endif
X#if EDITOR
Xpublic char * editor;
X#endif
X
Xextern int file;
Xextern int nbufs;
Xextern int sigs;
Xextern int quit_at_eof;
Xextern int p_nbufs, f_nbufs;
Xextern int back_scroll;
Xextern int top_scroll;
Xextern int sc_height;
Xextern int errmsgs;
X
X/* Prototypes for functions defined in main.c */
X
Xstatic void SeekRoot __PROTO((ULONG lock));
X
X
X#ifdef AMIGA
X/********** amiga **************/
X#include <ctype.h>
X#include <dos.h>
X#include <intuition/intuition.h>
X#include <exec/memory.h>
X#include <ios1.h>
X
Xextern struct UFB _ufbs[];
X
X/* Used by SeekRoot */
X#define MAXPATHSTRING 256
Xstatic char absDir[MAXPATHSTRING];
X
Xstruct IntuitionBase *IntuitionBase;
Xstruct Remember *RememberKey;
Xint called_from_WB = 0;
X
X
X/* max items and chars that *.c can expand to */
X#define MAXTEMPLATES 100
Xpublic char *local_argv[MAXTEMPLATES];
Xpublic int local_argc;
X#endif
X
X/*
X * Edit a new file.
X * Filename "-" means standard input.
X * No filename means the "current" file, from the command line.
X */
X#ifdef __STDC__
Xvoid edit (register char *filename)
X#else
X public void
Xedit(filename)
X register char *filename;
X#endif
X{
X register int f;
X register char *m;
X POSITION initial_pos;
X char message[100];
X char tempfile[FILENAME];
X static int didpipe;
X
X initial_pos = NULL_POSITION;
X if (filename == NULL || *filename == '\0')
X {
X if (curr_ac >= ac)
X {
X error("No current file");
X return;
X }
X filename = av[curr_ac];
X }
X if (strcmp(filename, "#") == 0)
X {
X if (*previous_file == '\0')
X {
X error("no previous file");
X return;
X }
X strtcpy(tempfile, previous_file, sizeof(tempfile));
X filename = tempfile;
X initial_pos = prev_pos;
X }
X if (strcmp(filename, "-") == 0)
X {
X /*
X * Use standard input.
X */
X if (didpipe)
X {
X error("Can view standard input only once");
X return;
X }
X f = 0;
X#ifdef AMIGA
X /* get standard input */
X if ( !chkufb(0) ) /* if linked with tinymain, we get no stdin */
X {
X _ufbs[0].ufbfh = Input();
X _ufbs[0].ufbflg |= UFB_RA | O_RAW;
X if ( !called_from_WB ) _ufbs[0].ufbflg |= UFB_NC;
X }
X#endif
X } else if ((m = bad_file(filename, message, sizeof(message))) != NULL)
X {
X error(m);
X return;
X } else if ((f = open(filename, 0)) < 0)
X {
X error(errno_message(filename, message, sizeof(message)));
X return;
X }
X
X#ifdef AMIGA
X/* SAS 5.10a isatty is broken; reports that pipe:x is a tty */
X if (isatty(f) && f==0)
X#else
X if (isatty(f))
X#endif
X {
X /*
X * Not really necessary to call this an error,
X * but if the control terminal (for commands)
X * and the input file (for data) are the same,
X * we get weird results at best.
X */
X error("Can't take input from a terminal");
X if (f > 0)
X close(f);
X return;
X }
X
X#if LOGFILE
X /*
X * If he asked for a log file and we have opened standard input,
X * create the log file.
X * We take care not to blindly overwrite an existing file.
X */
X end_logfile();
X if (f == 0 && namelogfile != NULL && is_tty)
X {
X int exists;
X int answer;
X
X /*
X * {{ We could use access() here. }}
X */
X exists = open(namelogfile, 0);
X close(exists);
X exists = (exists >= 0);
X
X if (exists && !force_logfile)
X {
X static char w[] = "WARNING: log file exists: ";
X strcpy(message, w);
X strtcpy(message+sizeof(w)-1, namelogfile,
X sizeof(message)-sizeof(w));
X error(message);
X answer = 'X'; /* Ask the user what to do */
X } else
X answer = 'O'; /* Create the log file */
X
X loop:
X switch (answer)
X {
X case 'O': case 'o':
X logfile = creat(namelogfile, 0644);
X break;
X case 'A': case 'a':
X logfile = open(namelogfile, 1);
X if (lseek(logfile, (offset_t)0, 2) < 0)
X {
X close(logfile);
X logfile = -1;
X }
X break;
X case 'D': case 'd':
X answer = 0; /* Don't print an error message */
X break;
X case 'q':
X quit();
X default:
X putstr("\n Overwrite, Append, or Don't log? ");
X answer = getchr();
X putstr("\n");
X flush();
X goto loop;
X }
X
X if (logfile < 0 && answer != 0)
X {
X sprintf(message, "Cannot write to \"%s\"",
X namelogfile);
X error(message);
X }
X }
X#endif
X
X /*
X * We are now committed to using the new file.
X * Close the current input file and set up to use the new one.
X */
X if (file > 0)
X close(file);
X new_file = 1;
X strtcpy(previous_file, current_file, sizeof(previous_file));
X strtcpy(current_file, filename, sizeof(current_file));
X prev_pos = position(TOP);
X#ifdef AMIGA
X /* Some heuristics to determine if we've been given a pipe.
X (there must be a better way...)
X */
X ispipe = ((f == 0) && !called_from_WB)
X || (strnicmp(filename, "pipe:", 5) == 0); /* kludge! */
X#else
X ispipe = (f == 0);
X#endif
X if (ispipe)
X didpipe = 1;
X file = f;
X ch_init( (ispipe) ? p_nbufs : f_nbufs );
X init_mark();
X
X if (every_first_cmd != NULL)
X first_cmd = every_first_cmd;
X
X if (is_tty)
X {
X int no_display = !any_display;
X any_display = 1;
X if (no_display && errmsgs > 0)
X {
X /*
X * We displayed some messages on error output
X * (file descriptor 2; see error() function).
X * Before erasing the screen contents,
X * display the file name and wait for a keystroke.
X */
X error(filename);
X }
X /*
X * Indicate there is nothing displayed yet.
X */
X pos_clear();
X if (initial_pos != NULL_POSITION)
X jump_loc(initial_pos);
X }
X}
X
X/*
X * Edit the next file in the command line list.
X */
X#ifdef __STDC__
Xvoid next_file (int n)
X#else
X public void
Xnext_file(n)
X int n;
X#endif
X{
X if (curr_ac + n >= ac)
X {
X if (quit_at_eof)
X quit();
X error("No (N-th) next file");
X } else
X edit(av[curr_ac += n]);
X}
X
X/*
X * Edit the previous file in the command line list.
X */
X#ifdef __STDC__
Xvoid prev_file (int n)
X#else
X public void
Xprev_file(n)
X int n;
X#endif
X{
X if (curr_ac - n < 0)
X error("No (N-th) previous file");
X else
X edit(av[curr_ac -= n]);
X}
X
X#ifndef AMIGA
X/*
X * Copy a file directly to standard output.
X * Used if standard output is not a tty.
X */
X static void
Xcat_file()
X{
X register int c;
X
X while ((c = ch_forw_get()) != EOF)
X putchr(c);
X flush();
X}
X#endif
X
X
X#ifdef AMIGA
X/**************** amiga *****************************/
X/* Bob Leivian 4/28/87 fudge up things so it will work
X when called from Work Bench */
X
Xchar argvbuf[80];
X
X#include "workbench/startup.h"
X
X#ifdef MANX
X/* ignore AZTECs wb stuff */
X_wb_parse(ignore, ignore2)
Xchar *ignore;
Xchar *ignore2;
X{
X return;
X}
X#endif
X#endif
X
X
X#ifdef NO_GETENV
X/* this requires the workbench disk --
X ignore all environment variables for now */
Xchar * getenv(ignore)
X{
X return NULL;
X}
X#endif
X
X/*
X * Entry point.
X */
X#ifdef __STDC__
Xint main (int argc, char **argv)
X#else
Xmain(argc, argv)
X int argc;
X char *argv[];
X#endif
X{
X char *getenv();
X
X
X#ifdef AMIGA
X/***************** amiga ********************/
X IntuitionBase = OpenLibrary ( "intuition.library", 0 );
X RememberKey = NULL;
X /* if we were called from the workbench we will have no args
X but a pointer to WBstruct, get the filename from this structure */
X if(argc == 0) {
X struct WBStartup *WBmsg;
X struct WBArg *p;
X char *cp, c;
X BPTR newlock;
X
X /* the argv is really the work bench structure */
X WBmsg = (struct WBStartup *) argv;
X p = WBmsg->sm_ArgList;
X
X /* fake up the args now */
X /* argv[0] = p->wa_Name; */
X p++; /* ignore first parm (name), since Less don't use it */
X for ( local_argc = 1; local_argc < WBmsg->sm_NumArgs
X && local_argc < MAXTEMPLATES; local_argc++ )
X {
X *absDir = '\0';
X /* SeekRoot UnLocks its argument */
X newlock = DupLock ( p->wa_Lock );
X SeekRoot ( newlock );
X /* The first part is really a device name */
X for ( cp=absDir; (c = *cp) && c != '/'; cp++ )
X /* nothing */;
X *cp = ':';
X if ( c == '\0' ) /* root dir of a device */
X *++cp = '\0';
X else
X strcat(cp, "/");
X if ( !(cp = AllocRemember(&RememberKey,
X strlen(absDir)+strlen(p->wa_Name)+1, 0L)) )
X quit();
X strcpy ( cp, absDir );
X local_argv[local_argc] = strcat(cp, p->wa_Name);
X p++;
X }
X local_argv[local_argc] = NULL;
X
X called_from_WB = 1;
X }
X
X
X#endif
X
X /*
X * Process command line arguments and LESS environment arguments.
X * Command line arguments override environment arguments.
X */
X init_option();
X scan_option(getenv("LESS"));
X argv++;
X while ( (--argc > 0) &&
X (argv[0][0] == '-' || argv[0][0] == '+') &&
X argv[0][1] != '\0')
X scan_option(*argv++);
X
X#if EDITOR
X editor = getenv("EDITOR");
X if (editor == NULL || *editor == '\0')
X editor = "ed";
X#endif
X
X /*
X * Set up list of files to be examined.
X */
X#ifdef AMIGA
X if ( called_from_WB )
X {
X ac = local_argc-1;
X av = local_argv+1; /* CLI case did an argv++ */
X }
X else
X {
X#endif
X ac = argc;
X av = argv;
X#ifdef AMIGA
X }
X#endif
X
X
X curr_ac = 0;
X
X /*
X * Set up terminal, etc.
X */
X#ifdef AMIGA
X is_tty = 1;
X ttopen();
X#else
X is_tty = isatty(1);
X if (!is_tty)
X {
X /*
X * Output is not a tty.
X * Just copy the input file(s) to output.
X */
X if (ac < 1)
X {
X edit("-");
X cat_file();
X } else
X {
X do
X {
X edit((char *)NULL);
X if (file >= 0)
X cat_file();
X } while (++curr_ac < ac);
X }
X quit();
X }
X#endif
X
X raw_mode(1);
X get_term();
X open_getchr();
X init();
X
X if (setjmp(main_loop))
X quit();
X init_signals();
X
X /*
X * Select the first file to examine.
X */
X if (ac < 1)
X edit("-"); /* Standard input */
X else
X {
X /*
X * Try all the files named as command arguments.
X * We are simply looking for one which can be
X * opened without error.
X */
X do
X {
X edit((char *)NULL);
X } while (file < 0 && ++curr_ac < ac);
X }
X
X if (file >= 0)
X commands();
X quit();
X /*NOTREACHED*/
X}
X
X/*
X * Copy a string, truncating to the specified length if necessary.
X * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
X */
X#ifdef __STDC__
Xvoid strtcpy (char *to, char *from, int len)
X#else
Xstrtcpy(to, from, len)
X char *to;
X char *from;
X int len;
X#endif
X{
X strncpy(to, from, len);
X to[len-1] = '\0';
X}
X
X/*
X * Exit the program.
X */
X#ifdef __STDC__
Xvoid quit (void)
X#else
X public void
Xquit()
X#endif
X{
X /*
X * Put cursor at bottom left corner, clear the line,
X * reset the terminal modes, and exit.
X */
X#if LOGFILE
X end_logfile();
X#endif
X#ifdef AMIGA
X ttclose();
X
X if (IntuitionBase)
X {
X FreeRemember( &RememberKey, 1 );
X CloseLibrary(IntuitionBase);
X }
X#else
X lower_left();
X clear_eol();
X deinit();
X
X flush();
X raw_mode(0);
X
X#endif
X
X exit(0);
X}
X
X
X#ifdef AMIGA
X
X/* Thanks to Bruce Rogers for a UseNet posting including the following
X useful function...
X*/
X
X/*!*******************************************************************
X * FindRoot by Bruce Rogers 1/20/90
X *********************************************************************/
X/*
X------------------------------------------------------ Quantum _\/_
X2727 Eel Bruce (6502 RULES!) Rogers |\ Duck ( 0 0)
XDavis, Ca 95616 Quantum Duck Software, |\ \______/ / \\\
X916-756-2684 rogers@iris.ucdavis.edu |\ < < | \/
X"My brain is on fire!" \________/ Quark!
X
X*/
X
X
X/*!*******************************************************************
X * Recursively go up parent chain, looking for oldest parent.
X * Create the absolute path string as we go.
X *********************************************************************/
Xstatic void SeekRoot(lock)
XULONG lock;
X{
Xstruct FileInfoBlock *fileInfo;
XULONG newlock;
Xchar NameEnd[MAXPATHSTRING], sep;
X
X fileInfo=AllocMem(sizeof(struct FileInfoBlock),0);
X
X Examine(lock,fileInfo);
X strcpy ( NameEnd, absDir );
X strcpy ( absDir, fileInfo->fib_FileName );
X sep = 0; if ( *absDir ) sep = absDir[strlen(absDir) - 1];
X if ( sep && *NameEnd && sep != '/' && sep != ':' ) strcat ( absDir, "/" );
X strcat ( absDir, NameEnd );
X newlock = ParentDir(lock);
X UnLock(lock);
X if (newlock!=NULL) SeekRoot(newlock);
X
X FreeMem(fileInfo,sizeof(struct FileInfoBlock));
X}
X#endif
END_OF_FILE
if test 16671 -ne `wc -c <'Less1.4Z/src/main.c'`; then
echo shar: \"'Less1.4Z/src/main.c'\" unpacked with wrong size!
fi
# end of 'Less1.4Z/src/main.c'
fi
if test -f 'Less1.4Z/src/screen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Less1.4Z/src/screen.c'\"
else
echo shar: Extracting \"'Less1.4Z/src/screen.c'\" \(20275 characters\)
sed "s/^X//" >'Less1.4Z/src/screen.c' <<'END_OF_FILE'
X/*
X * Routines which deal with the characteristics of the terminal.
X * Uses termcap to be as terminal-independent as possible.
X *
X * {{ Someday this should be rewritten to use curses. }}
X */
X
X#ifdef AMIGA
X/* Compile with -HPreHeader.q to get "less.h"! */
X#else
X#include "less.h"
X#endif
X
X#if XENIX
X#include <sys/types.h>
X#include <sys/ioctl.h>
X#endif
X
X#ifdef AMIGA
Xextern int sc_window_spec; /* user's requested -z */
Xextern int scroll; /* half-page scroll length */
Xextern int nrow, ncol;
X#else
X#if TERMIO
X#include <termio.h>
X#else
X#include <sgtty.h>
X#endif
X#endif
X
X#ifdef TIOCGWINSZ
X#include <sys/ioctl.h>
X#else
X/*
X * For the Unix PC (ATT 7300 & 3B1):
X * Since WIOCGETD is defined in sys/window.h, we can't use that to decide
X * whether to include sys/window.h. Use SIGWIND from sys/signal.h instead.
X */
X#include <signal.h>
X#ifdef SIGWIND
X#include <sys/window.h>
X#endif
X#endif
X
X
X/*
X * Strings passed to tputs() to do various terminal functions.
X */
Xstatic char
X *sc_pad, /* Pad string */
X *sc_home, /* Cursor home */
X *sc_addline, /* Add line, scroll down following lines */
X *sc_lower_left, /* Cursor to last line, first column */
X *sc_move, /* General cursor positioning */
X *sc_clear, /* Clear screen */
X *sc_eol_clear, /* Clear to end of line */
X *sc_s_in, /* Enter standout (highlighted) mode */
X *sc_s_out, /* Exit standout mode */
X *sc_u_in, /* Enter underline mode */
X *sc_u_out, /* Exit underline mode */
X *sc_b_in, /* Enter bold mode */
X *sc_b_out, /* Exit bold mode */
X#ifdef AMIGA
X *sc_it_in, /* Enter italic mode */
X *sc_it_out, /* Exit italic mode */
X *sc_nv_in, /* Enter inverse video mode */
X *sc_nv_out, /* Exit inverse video mode */
X#endif
X *sc_visual_bell, /* Visual bell (flash screen) sequence */
X *sc_backspace, /* Backspace cursor */
X *sc_init, /* Startup terminal initialization */
X *sc_deinit; /* Exit terminal de-intialization */
X#ifdef DUMBTERM
Xstatic int dumb;
X#endif
Xstatic int hard;
X
Xpublic int auto_wrap; /* Terminal does \r\n when write past margin */
Xpublic int ignaw; /* Terminal ignores \n immediately after wrap */
Xpublic int erase_char, kill_char; /* The user's erase and line-kill chars */
Xpublic int sc_width, sc_height; /* Height & width of screen */
Xpublic int sc_window = -1; /* window size for forward and backward */
Xpublic int bo_width, be_width; /* Printing width of boldface sequences */
Xpublic int ul_width, ue_width; /* Printing width of underline sequences */
Xpublic int so_width, se_width; /* Printing width of standout sequences */
Xpublic int it_width, ie_width; /* Printing width of italic sequences */
Xpublic int nv_width, ne_width; /* Printing width of inv video sequences */
X
X/*
X * These two variables are sometimes defined in,
X * and needed by, the termcap library.
X * It may be necessary on some systems to declare them extern here.
X */
X/*extern*/ short ospeed; /* Terminal output baud rate */
X/*extern*/ char PC; /* Pad character */
X
Xextern int quiet; /* If VERY_QUIET, use visual bell for bell */
X#ifdef DUMBTERM
Xextern int know_dumb; /* Don't complain about a dumb terminal */
X#endif
Xextern int back_scroll;
Xchar *tgetstr();
Xchar *tgoto();
X
X/*
X * Change terminal to "raw mode", or restore to "normal" mode.
X * "Raw mode" means
X * 1. An outstanding read will complete on receipt of a single keystroke.
X * 2. Input is not echoed.
X * 3. On output, \n is mapped to \r\n.
X * 4. \t is NOT expanded into spaces.
X * 5. Signal-causing characters such as ctrl-C (interrupt),
X * etc. are NOT disabled.
X * It doesn't matter whether an input \n is mapped to \r, or vice versa.
X */
X#ifdef __STDC__
Xvoid raw_mode (int on)
X#else
X public void
Xraw_mode(on)
X int on;
X#endif
X{
X#ifdef AMIGA
X extern int do_echo;
X
X if (on)
X do_echo = 0;
X else
X do_echo = 1;
X erase_char = 8; /* ^H */
X kill_char = 24; /* ^X */
X#else
X#if TERMIO
X struct termio s;
X static struct termio save_term;
X
X if (on)
X {
X /*
X * Get terminal modes.
X */
X ioctl(2, TCGETA, &s);
X
X /*
X * Save modes and set certain variables dependent on modes.
X */
X save_term = s;
X ospeed = s.c_cflag & CBAUD;
X erase_char = s.c_cc[VERASE];
X kill_char = s.c_cc[VKILL];
X
X /*
X * Set the modes to the way we want them.
X */
X s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
X s.c_oflag |= (OPOST|ONLCR|TAB3);
X s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
X s.c_cc[VMIN] = 1;
X s.c_cc[VTIME] = 0;
X } else
X {
X /*
X * Restore saved modes.
X */
X s = save_term;
X }
X ioctl(2, TCSETAW, &s);
X#else
X struct sgttyb s;
X static struct sgttyb save_term;
X
X if (on)
X {
X /*
X * Get terminal modes.
X */
X ioctl(2, TIOCGETP, &s);
X
X /*
X * Save modes and set certain variables dependent on modes.
X */
X save_term = s;
X ospeed = s.sg_ospeed;
X erase_char = s.sg_erase;
X kill_char = s.sg_kill;
X
X /*
X * Set the modes to the way we want them.
X */
X s.sg_flags |= CBREAK;
X s.sg_flags &= ~(ECHO|XTABS);
X } else
X {
X /*
X * Restore saved modes.
X */
X s = save_term;
X }
X ioctl(2, TIOCSETN, &s);
X#endif
X#endif
X}
X
X#ifdef DUMBTERM
X static void
Xcannot(s)
X char *s;
X{
X char message[100];
X
X if (know_dumb)
X /*
X * He knows he has a dumb terminal, so don't tell him.
X */
X return;
X
X sprintf(message, "WARNING: terminal cannot \"%s\"", s);
X error(message);
X}
X#endif
X
X#ifdef AMIGA
X/*
X * Set forward and backward scrolling limits based upon user's requests
X * and screen size
X */
X#ifdef __STDC__
Xvoid set_scroll (void)
X#else
X public void
Xset_scroll()
X#endif
X{
X if (sc_window_spec > 0)
X sc_window = (sc_window_spec < nrow? sc_window_spec: nrow - 1);
X else
X sc_window = nrow - 1;
X}
X#endif
X
X/*
X * Get terminal capabilities via termcap.
X */
X#ifdef __STDC__
Xvoid get_term (void)
X#else
X public void
Xget_term()
X#endif
X{
X#ifdef AMIGA
X static char go_to_home[10];
X
X getrowcol(); /* find out window size */
X scroll = nrow/2;
X set_scroll();
X
X/* I didn't want to port termcap for now, but there is a version
X on fish #14 that someone might want to use */
X sc_pad = ""; /* Pad string */
X sc_home = "\x9b\x31;1H"; /* Cursor home */
X sc_addline = "\x9bL"; /* Add line, scroll down following lines */
X sprintf(go_to_home, "\x9b%d;1H", nrow);
X sc_lower_left = go_to_home; /* Cursor to last line, first column */
X sc_move = ""; /* General cursor positioning */
X sc_clear = "\f"; /* Clear screen */
X sc_eol_clear = "\x9bK"; /* Clear to end of line */
X sc_s_in = "\x9b\x37m"; /* Enter standout (highlighted) mode */
X sc_s_out = "\x9b\x30m"; /* Exit standout mode */
X sc_u_in = "\x9b\x34m"; /* Enter underline mode */
X sc_u_out = "\x9b\x30m"; /* Exit underline mode */
X sc_b_in = "\x9b\x31m"; /* Enter bold mode */
X sc_b_out = "\x9b\x30m"; /* Exit bold mode */
X sc_it_in = "\x9b\x33m"; /* Enter italic mode */
X sc_it_out = "\x9b\x30m"; /* Exit italic mode */
X sc_nv_in = "\x9b\x37m"; /* Enter inverse video mode */
X sc_nv_out = "\x9b\x30m"; /* Exit inverse video mode */
X /* We define visual_bell to be null, because on the Amiga the
X ordinary BELL signal (^G) does a visual bell. Thus, in the
X Amiga version of Less, the user's choice is between a visual
X bell (not quiet) and no indicator at all (quiet)
X */
X sc_visual_bell = NULL; /* Visual bell (flash screen) sequence */
X sc_backspace = "\b"; /* Backspace cursor */
X sc_init = ""; /* Startup terminal initialization */
X sc_deinit = ""; /* Exit terminal de-intialization */
X sc_height = nrow;
X sc_width = ncol;
X
X so_width = 0;
X it_width = ie_width = nv_width = ne_width =
X be_width = bo_width = ue_width = ul_width = se_width = so_width;
X
X#else
X char termbuf[2048];
X char *sp;
X#ifdef TIOCGWINSZ
X struct winsize w;
X#else
X#ifdef WIOCGETD
X struct uwdata w;
X#endif
X#endif
X static char sbuf[1024];
X
X char *getenv();
X
X /*
X * Find out what kind of terminal this is.
X */
X if (tgetent(termbuf, getenv("TERM")) <= 0)
X dumb = 1;
X
X /*
X * Get size of the screen.
X */
X#ifdef TIOCGWINSZ
X if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_row)
X sc_height = w.ws_row;
X else
X#else
X#ifdef WIOCGETD
X if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_height)
X sc_height = w.uw_height/w.uw_vs;
X else
X#endif
X#endif
X sc_height = tgetnum("li");
X if (dumb || sc_height < 0 || tgetflag("hc"))
X {
X /* Oh no, this is a hardcopy terminal. */
X hard = 1;
X sc_height = 24;
X }
X /*
X * This is terrible - the following if "knows" that it is being
X * executed *after* command line and environment options have
X * already been parsed. Should it be executed in the main program
X * instead?
X */
X if ((sc_window <= 0) || (sc_window >= sc_height))
X sc_window = sc_height-1;
X
X#ifdef TIOCGWINSZ
X if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_col)
X sc_width = w.ws_col;
X else
X#ifdef WIOCGETD
X if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_width)
X sc_width = w.uw_width/w.uw_hs;
X else
X#endif
X#endif
X sc_width = tgetnum("co");
X if (dumb || sc_width < 0)
X sc_width = 80;
X
X auto_wrap = tgetflag("am");
X ignaw = tgetflag("xn");
X
X /*
X * Assumes termcap variable "sg" is the printing width of
X * the standout sequence, the end standout sequence,
X * the underline sequence, the end underline sequence,
X * the boldface sequence, and the end boldface sequence.
X */
X if ((so_width = tgetnum("sg")) < 0)
X so_width = 0;
X be_width = bo_width = ue_width = ul_width = se_width = so_width;
X
X /*
X * Get various string-valued capabilities.
X */
X sp = sbuf;
X
X sc_pad = (dumb) ? NULL : tgetstr("pc", &sp);
X if (sc_pad != NULL)
X PC = *sc_pad;
X
X sc_init = (dumb) ? NULL : tgetstr("ti", &sp);
X if (sc_init == NULL)
X sc_init = "";
X
X sc_deinit= (dumb) ? NULL : tgetstr("te", &sp);
X if (sc_deinit == NULL)
X sc_deinit = "";
X
X sc_eol_clear = (dumb) ? NULL : tgetstr("ce", &sp);
X if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')
X {
X cannot("clear to end of line");
X sc_eol_clear = "";
X }
X
X sc_clear = (dumb) ? NULL : tgetstr("cl", &sp);
X if (hard || sc_clear == NULL || *sc_clear == '\0')
X {
X cannot("clear screen");
X sc_clear = "\n\n";
X }
X
X sc_move = (dumb) ? NULL : tgetstr("cm", &sp);
X if (hard || sc_move == NULL || *sc_move == '\0')
X {
X /*
X * This is not an error here, because we don't
X * always need sc_move.
X * We need it only if we don't have home or lower-left.
X */
X sc_move = "";
X }
X
X sc_s_in = (dumb) ? NULL : tgetstr("so", &sp);
X if (hard || sc_s_in == NULL)
X sc_s_in = "";
X
X sc_s_out = (dumb) ? NULL : tgetstr("se", &sp);
X if (hard || sc_s_out == NULL)
X sc_s_out = "";
X
X sc_u_in = (dumb) ? NULL : tgetstr("us", &sp);
X if (hard || sc_u_in == NULL)
X sc_u_in = sc_s_in;
X
X sc_u_out = (dumb) ? NULL : tgetstr("ue", &sp);
X if (hard || sc_u_out == NULL)
X sc_u_out = sc_s_out;
X
X sc_b_in = (dumb) ? NULL : tgetstr("md", &sp);
X if (hard || sc_b_in == NULL)
X {
X sc_b_in = sc_s_in;
X sc_b_out = sc_s_out;
X } else
X {
X sc_b_out = (dumb) ? NULL : tgetstr("me", &sp);
X if (hard || sc_b_out == NULL)
X sc_b_out = "";
X }
X
X sc_visual_bell = (dumb) ? NULL : tgetstr("vb", &sp);
X if (hard || sc_visual_bell == NULL)
X sc_visual_bell = "";
X
X sc_home = (dumb) ? NULL : tgetstr("ho", &sp);
X if (hard || sc_home == NULL || *sc_home == '\0')
X {
X if (*sc_move == '\0')
X {
X cannot("home cursor");
X /*
X * This last resort for sc_home is supposed to
X * be an up-arrow suggesting moving to the
X * top of the "virtual screen". (The one in
X * your imagination as you try to use this on
X * a hard copy terminal.)
X */
X sc_home = "|\b^";
X } else
X {
X /*
X * No "home" string,
X * but we can use "move(0,0)".
X */
X strcpy(sp, tgoto(sc_move, 0, 0));
X sc_home = sp;
X sp += strlen(sp) + 1;
X }
X }
X
X sc_lower_left = (dumb) ? NULL : tgetstr("ll", &sp);
X if (hard || sc_lower_left == NULL || *sc_lower_left == '\0')
X {
X if (*sc_move == '\0')
X {
X cannot("move cursor to lower left of screen");
X sc_lower_left = "\r";
X } else
X {
X /*
X * No "lower-left" string,
X * but we can use "move(0,last-line)".
X */
X strcpy(sp, tgoto(sc_move, 0, sc_height-1));
X sc_lower_left = sp;
X sp += strlen(sp) + 1;
X }
X }
X
X /*
X * To add a line at top of screen and scroll the display down,
X * we use "al" (add line) or "sr" (scroll reverse).
X */
X if (dumb)
X sc_addline = NULL;
X else if ((sc_addline = tgetstr("al", &sp)) == NULL ||
X *sc_addline == '\0')
X sc_addline = tgetstr("sr", &sp);
X
X if (hard || sc_addline == NULL || *sc_addline == '\0')
X {
X cannot("scroll backwards");
X sc_addline = "";
X /* Force repaint on any backward movement */
X back_scroll = 0;
X }
X
X if (dumb || tgetflag("bs"))
X sc_backspace = "\b";
X else
X {
X sc_backspace = tgetstr("bc", &sp);
X if (sc_backspace == NULL || *sc_backspace == '\0')
X sc_backspace = "\b";
X }
X#endif
X}
X
X
X/*
X * Below are the functions which perform all the
X * terminal-specific screen manipulation.
X */
X
X
X/*
X * Initialize terminal
X */
X#ifdef __STDC__
Xvoid init (void)
X#else
X public void
Xinit()
X#endif
X{
X tputs(sc_init, sc_height, putchr);
X}
X
X/*
X * Deinitialize terminal
X */
X#ifdef __STDC__
Xvoid deinit (void)
X#else
X public void
Xdeinit()
X#endif
X{
X tputs(sc_deinit, sc_height, putchr);
X}
X
X/*
X * Home cursor (move to upper left corner of screen).
X */
X#ifdef __STDC__
Xvoid home (void)
X#else
X public void
Xhome()
X#endif
X{
X tputs(sc_home, 1, putchr);
X}
X
X/*
X * Add a blank line (called with cursor at home).
X * Should scroll the display down.
X */
X#ifdef __STDC__
Xvoid add_line (void)
X#else
X public void
Xadd_line()
X#endif
X{
X tputs(sc_addline, sc_height, putchr);
X}
X
X/*
X * Move cursor to lower left corner of screen.
X */
X#ifdef __STDC__
Xvoid lower_left (void)
X#else
X public void
Xlower_left()
X#endif
X{
X tputs(sc_lower_left, 1, putchr);
X}
X
X/*
X * Ring the terminal bell.
X */
X#ifdef __STDC__
Xvoid bell (void)
X#else
X public void
Xbell()
X#endif
X{
X if (quiet == VERY_QUIET)
X vbell();
X else
X putchr('\7');
X}
X
X/*
X * Output the "visual bell", if there is one.
X */
X#ifdef __STDC__
Xvoid vbell (void)
X#else
X public void
Xvbell()
X#endif
X{
X if (*sc_visual_bell == '\0')
X return;
X tputs(sc_visual_bell, sc_height, putchr);
X}
X
X/*
X * Clear the screen.
X */
X#ifdef __STDC__
Xvoid clear (void)
X#else
X public void
Xclear()
X#endif
X{
X tputs(sc_clear, sc_height, putchr);
X}
X
X/*
X * Clear from the cursor to the end of the cursor's line.
X * {{ This must not move the cursor. }}
X */
X#ifdef __STDC__
Xvoid clear_eol (void)
X#else
X public void
Xclear_eol()
X#endif
X{
X tputs(sc_eol_clear, 1, putchr);
X}
X
X/*
X * Begin "standout" (bold, underline, or whatever).
X */
X#ifdef __STDC__
Xvoid so_enter (void)
X#else
X public void
Xso_enter()
X#endif
X{
X tputs(sc_s_in, 1, putchr);
X}
X
X/*
X * End "standout".
X */
X#ifdef __STDC__
Xvoid so_exit (void)
X#else
X public void
Xso_exit()
X#endif
X{
X tputs(sc_s_out, 1, putchr);
X}
X
X/*
X * Begin "underline" (hopefully real underlining,
X * otherwise whatever the terminal provides).
X */
X#ifdef __STDC__
Xvoid ul_enter (void)
X#else
X public void
Xul_enter()
X#endif
X{
X tputs(sc_u_in, 1, putchr);
X}
X
X/*
X * End "underline".
X */
X#ifdef __STDC__
Xvoid ul_exit (void)
X#else
X public void
Xul_exit()
X#endif
X{
X tputs(sc_u_out, 1, putchr);
X}
X
X/*
X * Begin "bold"
X */
X#ifdef __STDC__
Xvoid bo_enter (void)
X#else
X public void
Xbo_enter()
X#endif
X{
X tputs(sc_b_in, 1, putchr);
X}
X
X/*
X * End "bold".
X */
X#ifdef __STDC__
Xvoid bo_exit (void)
X#else
X public void
Xbo_exit()
X#endif
X{
X tputs(sc_b_out, 1, putchr);
X}
X
X#ifdef AMIGA
X/*
X * Begin "italic" mode
X */
X#ifdef __STDC__
Xvoid it_enter (void)
X#else
X public void
Xit_enter()
X#endif
X{
X tputs(sc_it_in, 1, putchr);
X}
X
X/*
X * End "italic"
X */
X#ifdef __STDC__
Xvoid it_exit (void)
X#else
X public void
Xit_exit()
X#endif
X{
X tputs(sc_it_out, 1, putchr);
X}
X
X/*
X * Begin "inverse video"
X */
X#ifdef __STDC__
Xvoid nv_enter (void)
X#else
X public void
Xnv_enter()
X#endif
X{
X tputs(sc_nv_in, 1, putchr);
X}
X
X/*
X * End "inverse video"
X */
X#ifdef __STDC__
Xvoid nv_exit (void)
X#else
X public void
Xnv_exit()
X#endif
X{
X tputs(sc_nv_out, 1, putchr);
X}
X#endif
X
X/*
X * Erase the character to the left of the cursor
X * and move the cursor left.
X */
X#ifdef __STDC__
Xvoid backspace (void)
X#else
X public void
Xbackspace()
X#endif
X{
X /*
X * Try to erase the previous character by overstriking with a space.
X */
X tputs(sc_backspace, 1, putchr);
X putchr(' ');
X tputs(sc_backspace, 1, putchr);
X}
X
X/*
X * Output a plain backspace, without erasing the previous char.
X */
X#ifdef __STDC__
Xvoid putbs (void)
X#else
X public void
Xputbs()
X#endif
X{
X tputs(sc_backspace, 1, putchr);
X}
END_OF_FILE
if test 20275 -ne `wc -c <'Less1.4Z/src/screen.c'`; then
echo shar: \"'Less1.4Z/src/screen.c'\" unpacked with wrong size!
fi
# end of 'Less1.4Z/src/screen.c'
fi
echo shar: End of archive 3 \(of 7\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 7 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.